package com.game.center.service;

import java.time.Duration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.alibaba.fastjson.JSON;
import com.game.center.logicconfig.EnumRedisKey;
import com.game.center.messages.GameCenterError;
import com.game.center.messages.request.CreatePlayerParam;
import com.game.framework.dao.entity.PlayerBasic;
import com.game.framework.dao.redis.CommonRedisKeyConifg;
import com.game.network.message.error.GameErrorException;

public abstract class AbstractPlayerService implements IPlayerService {
	@Autowired
	private StringRedisTemplate redisTemplate;

	private Logger logger = LoggerFactory.getLogger(AbstractPlayerService.class);

	private boolean saveNickNameIfAbsent(String nickName) {
		String key = this.getNickNameRedisKey(nickName);
		Boolean result = redisTemplate.opsForValue().setIfAbsent(key, "0");// value先使用一个默认值
		if (result == null) {
			return false;
		}
		return result;
	}

	private String getNickNameRedisKey(String nickName) {
		String key = EnumRedisKey.PLAYER_NICKNAME.getKey(nickName);
		return key;
	}

	private void updatePlayerIdForNickName(String nickName, long playerId) {
		String key = this.getNickNameRedisKey(nickName);
		this.redisTemplate.opsForValue().set(key, String.valueOf(playerId));
	}

	@Override
	public PlayerBasic createPlayer(CreatePlayerParam param, long userId) {
		String nickName = param.getNickName();
		boolean saveNickName = this.saveNickNameIfAbsent(nickName);
		if (!saveNickName) {// 如果存储失败，抛出错误异常
			throw new GameErrorException.Builder(GameCenterError.NICKNAME_EXIST).message(nickName).build();
		}
		long playerId = this.nextPlayerId();// 获取一个全局playerId。
		
		this.updatePlayerIdForNickName(nickName, playerId);// 再次更新一下nickName对应的playerId
		PlayerBasic playerBasic = new PlayerBasic();
		playerBasic.setUserId(userId);
		playerBasic.setPlayerId(playerId);
		playerBasic.setNickName(nickName);
		PlayerBasic realPlayer = this.createRealPlayer(playerBasic);
		this.updatePlayer(realPlayer);
		logger.info("创建角色成功,{}", realPlayer);
		return realPlayer;
	}

	protected Duration getPlayerRedisExpire() {
		return CommonRedisKeyConifg.PLAYER_INFO.getExpire();
	}

	protected abstract PlayerBasic createRealPlayer(PlayerBasic playerBasic);
	
	public abstract void updatePlayer(PlayerBasic playerBasic);

	private long nextPlayerId() {
		String key = EnumRedisKey.PLAYER_ID_INCR.getKey();
		return redisTemplate.opsForValue().increment(key);
	}

}
